package com.tdrc.shop.service;

import com.tdrc.common.util.CommonUtil;
import com.tdrc.shop.beans.Good;
import com.tdrc.shop.beans.GoodOrder;
import com.tdrc.shop.mapper.GoodMapper;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @author dpf
 * @version 1.0
 * @date 2020-4-28 14:56
 * @instruction ...
 */
@Service
public class GoodService implements IGoodService {
    @Resource
    private GoodMapper goodMapper;
    @Resource
    private StringRedisTemplate stringRedisTemplate;
  /*  @Resource
    private CuratorFramework curatorFramework;*/
    @Override
    public void addGoodOrder(GoodOrder goodOrder) {
        goodMapper.addGoodOrder(goodOrder);
    }

    @Override
    public int updateGoodInfo(Good good) {
          return goodMapper.updateGoodInfo(good);
    }

    @Override
    public Good getGoodByGoodId(Integer goodId) {
        return goodMapper.getGoodByGoodId(goodId);
    }

    /**
     * 基于redis分布式锁
     * @param goodId
     * @param quantity
     * @param userId
     * @return
     */
    @Override
    public boolean seckilByRedisLock(Integer goodId, Integer quantity,Integer userId) throws Exception {
       Boolean result=false;
            ValueOperations valueOperations=stringRedisTemplate.opsForValue();
            final String key=new StringBuffer().append(goodId).append(userId).append("-RedisLock").toString();
            final String value= UUID.randomUUID().toString();
            Boolean cacheRes=valueOperations.setIfAbsent(key,value);
            if (cacheRes){
                stringRedisTemplate.expire(key,30, TimeUnit.SECONDS);
                try {
                    Good good = goodMapper.getGoodByGoodId(goodId);
                    if (good.getQuantity()>0){
                        //减库存操作
                        int res=goodMapper.updateGoodInfo(new Good(goodId,good.getVersion()));
                         if (res>0){
                            GoodOrder goodOrder =  new GoodOrder();
                            System.out.println("下单成功ID为"+userId);
                            goodOrder.setGoodId(goodId);
                            goodOrder.setOrderQuantity(quantity);
                            goodOrder.setOrderTime(CommonUtil.dateTimeToStr(LocalDateTime.now()));
                            goodOrder.setUserId(userId);
                            goodMapper.addGoodOrder(goodOrder);
                            result= true;
                        }
                    }
                }catch (Exception e){
                    e.printStackTrace();
                    throw new Exception("还没到抢购日期、已过了抢购时间或已被抢购完毕！");
                }finally {
                    if (value.equals(valueOperations.get(key).toString())){
                        stringRedisTemplate.delete(key);
                        System.out.println("--------------释放锁成功--------------");
                    }
                }
            }

        return result;

    }
    /**
     * 基于zookeeper分布式锁
     * @param goodId
     * @param quantity
     * @param userId
     */
    @Override
    public boolean seckilByZookeeper(Integer goodId, Integer quantity, Integer userId) throws Exception {
        boolean result = false;
        //定义获取分布式锁的操作组件实例
        /* InterProcessMutex mutex=new InterProcessMutex(curatorFramework,"/kill/zklock/"+goodId+userId+"-lock");
        try {
            //尝试获取分布式锁
             if (mutex.acquire(10L, TimeUnit.SECONDS)){
                Good good = goodMapper.getGoodByGoodId(goodId);
                if (good.getQuantity() == 0) {  //如果库存为空
                    result= false;
                }else{
                    int res=goodMapper.updateGoodInfo(new Good(goodId,good.getVersion())); //减库存操作
                    if(res>0){
                        GoodOrder goodOrder =  new GoodOrder();
                        goodOrder.setGoodId(goodId);
                        goodOrder.setOrderQuantity(quantity);
                        goodOrder.setOrderTime(CommonUtil.dateTimeToStr(LocalDateTime.now()));
                        goodOrder.setUserId(userId);
                        goodMapper.addGoodOrder(goodOrder);
                        result= true;
                    }else{
                        result= false;
                    }
                }
             }else{
                 result = false;
             }
        }catch (Exception e){
            System.out.println("秒杀失败！");
            result = false;
        }finally {
            //释放分布式锁
            if (mutex!=null) {
                mutex.release();
            }
        }*/
        return result;
    }
}
